

#define SYS_STACK_SIZE 1024
#define ERR_PCB_EXISTS -200
#define UNRECOGNIZED_DEVICE -1000
#define UNRECOGNIZED_REQUEST -1001
#define INV_GOTOXY_REQ -1002

#define COMHAN_STACK_SIZE 4000


typedef struct context{
	unsigned int BP, DI, SI, DS, ES;
	unsigned int DX, CX, BX, AX;
	unsigned int IP, CS, FLAGS;
} context;

typedef struct params{
	int op_code; //operation code, IDLE, EXIT, READ, WRITE, etc
	int device_id; //TERMINAL, COM_PORT
	unsigned char *buf_addr; //buffer address
	int *count_addr; //size of the buffer
} params;

//function prototypes
void interrupt sys_call(void);
void interrupt dispatch(void);
int init_stack_and_rq(void);

//temporary commands/functions
int load_procs(void);
int dispatch_command(char args[MAX_NARGS][MAX_ARGLEN], int nArgs);
int loadr3_command(char args[MAX_NARGS][MAX_ARGLEN], int nArgs);

//test procedures
void test1_R3(void);
void test2_R3(void);
void test3_R3(void);
void test4_R3(void);
void test5_R3(void);

///////////\\\\\\\\\\
/* R6 ADDITIONS!!! */
///////////\\\\\\\\\\

/* data structures */

typedef struct iod iod; // I/O Request Descriptor
struct iod{
	char requestor_name[MAX_ARGLEN];
	pcb* requestor;
	int request_type; // one of {IDLE,READ,WRITE,CLEAR}
	char* buf_addr; // location of transfer buffer
	int* count_addr; //ptr to transfer buffer count
	struct iod* next_ptr; //ptr to next iod in iod waiting queue
	
	/* Note that the request type, transfer buffer, and count
		variable refer to the op_code, buffer_address, and 
		count_address in the param struct used in r3code.h */ 
}; 

/* I/O Control Block
	Keeps track of iod waiting queue and current status */
typedef struct {
	int event_flag; // current event flag for the device
	int q_count; // number of iod's in the iod queue
	iod* head_ptr; // ptr to head iod of waiting queue
	iod* tail_ptr; // ptr to the last iod in the waiting queue
	/* waiting queues will be maintained in FIFO order */
} iocb; 


/* function prototypes */
int load_init_procs(void); //load comhan process and IDLE process
int scheduleIO(void);//create a new iod for an i/o request
int processIOrequest(void); //process an i/o request
int init_io(void); //initalize iocbs and open devices
void io_end(void); //close devices, clear iocb queues, free any iod's memory, and finally free the iocbs
void end_all_processes(void); //empty/free the pcbs/pcbQueues
